﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Collections;
using System.Threading;

namespace ControlesAWIL
{
    //-- esto es para que el campo se pueda asociar a un bindingSource en tiempo de diseño.
    [System.ComponentModel.DefaultBindingProperty("AWIL_Texto")]

    public partial class BuscadorAWIL : UserControl
    {
        /// <summary>
        /// Declaracion de EVENTOS
        /// </summary>
        public event EventHandler AWIL_TextChanged;
        

        public BuscadorAWIL()
        {
            InitializeComponent();
            this.widthInicialTextBoxFiltro = this.textBoxFiltro.Width;
            //--- inicializa los eventos
            this.textBoxFiltro.TextChanged += new EventHandler(textBoxFiltro_TextChanged_2);            
        }

        /// <summary>
        /// EVENTO: TextChanged Del control
        /// </summary>
        private void textBoxFiltro_TextChanged_2(object sender, EventArgs e)
        {
            if (this.AWIL_TextChanged != null)
            {
                this.AWIL_TextChanged(this, e);
            }
        }


        private string valorActual;// = string.Empty;

        private FormatoTexto formatoTexto = FormatoTexto.Texto;
        private VentanaBuscador ventanaBuscador = new VentanaBuscador();
        private BindingSource bindingSource = null;
        private string ocultarColumnas = "Id,FechaGrab,UsuarioGrab,FechaUltMod,UsuarioUltMod,";
        private DataRowView dataRowCurrent = null;

        private string columnaRetorno = "Id";
        private string columnaDescripcion = "Id";
        private int numeroDecimales = 0;
        private bool validarCampo = true;  //--- Este campo impide que el usuario pase por el campo sin seleccionar un valor valido
        private bool mostrarDescripcion = true;  //--- Este campo impide que el usuario pase por el campo sin seleccionar un valor valido
        private int widthInicialTextBoxFiltro = 0;

        /// <summary>
        /// Las columnas de la tabla que se agregen en este campo NO se mostraran en la ventana emergente del buscador
        /// </summary>
        public string AWIL_OcultarColumnas
        {
            get { return ocultarColumnas; }
            set{ocultarColumnas = value;}
        }

        /// <summary>
        /// Devuelve el DataRow actual para El DataTable consultado por el buscador
        /// </summary>
        public DataRowView AWIL_DataRowCurrent
        {
            get { return this.dataRowCurrent; }            
        }
        
        /// <summary>
        /// Indica si se debe validar que el usuario digite un valor correcto en el buscador
        /// </summary>
        public bool AWIL_ValidarCampo
        {
            get { return validarCampo; }
            set{validarCampo = value;
            this.textBoxFiltro.ForeColor = (!value ? Color.Black : this.textBoxFiltro.ForeColor);
            }
        }

        /// <summary>
        /// Indica si se mostrara el campo descriptivo del buscador
        /// </summary>
        public bool AWIL_MostrarDescripcion
        {
            get { return mostrarDescripcion; }
            set
            {
                mostrarDescripcion = value;
                this.textBox2.Visible = value;
                
                if (value)
                {
                    this.textBoxFiltro.Width = this.widthInicialTextBoxFiltro;
                    this.Width = this.textBoxFiltro.Width + textBox2.Width + pictureBoxIcono.Width;
                    this.textBoxFiltro.Anchor = ((AnchorStyles.Left) | AnchorStyles.Top);
                    this.pictureBoxIcono.Anchor = ((AnchorStyles.Left) | AnchorStyles.Top);
                }
                else
                {
                    this.Width = this.textBoxFiltro.Width + pictureBoxIcono.Width;
                    this.textBoxFiltro.Anchor = (((AnchorStyles.Left) | AnchorStyles.Top) | AnchorStyles.Right);
                    this.pictureBoxIcono.Anchor = ((AnchorStyles.Right) | AnchorStyles.Top);
                }
            }
        }


        /// <summary>
        /// Devuelve o Cambia el BindingSource asociado al buscador
        /// </summary>
        public BindingSource AWIL_BindingSource
        {
            get { return bindingSource; }
            set
            {
                bindingSource = value;
                try
                {
                    //--- la siguiente validacion es para evitar que se rompa cuando la solucion este diseñando el formulario.
                    this.columnaDescripcion = (this.columnaDescripcion == string.Empty ? "Id" : this.columnaDescripcion);
                    this.columnaRetorno = (this.columnaRetorno == string.Empty ? "Id" : this.columnaRetorno);
                }
                catch (Exception e)
                {
                    MessageBox.Show(e.Message);
                }
            }
        }

        /// <summary>
        /// Devuelve el texto del buscador 
        /// </summary>
        public string AWIL_Texto
        {
            get { return this.textBoxFiltro.Text.Trim(); }
            set { this.textBoxFiltro.Text = value.Trim(); 
            }
        }

        /// <summary>
        /// Devuelve el texto de la descripcion del buscador 
        /// </summary>
        public string AWIL_TextoDescripcion
        {
            get { return this.textBox2.Text.Trim(); }
            //set { this.textBoxFiltro.Text = value.Trim(); }
        }

        /// <summary>
        /// Longitud maxima del texto del buscador
        /// </summary>
        public int AWIL_MaxLength
        {
            get { return this.textBoxFiltro.MaxLength; }
            set
            {
                if (value < 0 || value > 32000)
                {
                    return;
                }
                this.textBoxFiltro.MaxLength = value;
            }
        }

        /// <summary>
        /// Columna que sera retorna por el buscador
        /// </summary>
        public string AWIL_ColumnaRetorno
        {
            get { return columnaRetorno; }
            set
            {
                if (value == "")
                {
                    columnaRetorno = "Id";
                }
                else
                {
                    columnaRetorno = value;
                }
            }
        }

        /// <summary>
        /// Columna que se mostrara en el campo Descriptivo del buscador
        /// </summary>
        public string AWIL_ColumnaDescripcion
        {
            get { return columnaDescripcion; }
            set
            {
                if (value == "")
                {
                    columnaDescripcion = "Id";
                }
                else
                {
                    columnaDescripcion = value;
                }
            }
        }
        
        /// <summary>
        /// Numero de decimales del buscador (esto solo aplica cuando AWIL_FormatoTexto=Numero)
        /// </summary>
        public int AWIL_NumeroDecimales
        {
            get { return numeroDecimales; }
            set
            {
                if (formatoTexto == FormatoTexto.Texto && this.numeroDecimales != 0)
                {
                    MessageBox.Show("Esta Propiedad Solo aplica Para Numeros");
                    numeroDecimales = 0;
                    return;
                }
                if (value > 0 && value < 10)
                {
                    numeroDecimales = value;
                }
                else
                {
                    numeroDecimales = 0;
                }
            }
        }

        /// <summary>
        /// Formato del buscador. Texto o Numero.        
        /// </summary>
        public FormatoTexto AWIL_FormatoTexto
        {
            get { return formatoTexto; }
            set
            {
                if (value == FormatoTexto.Texto)
                {
                    this.numeroDecimales = 0;
                    this.textBoxFiltro.TextAlign = HorizontalAlignment.Left;
                }
                else
                {
                    this.textBoxFiltro.TextAlign = HorizontalAlignment.Right;
                }
                formatoTexto = value;
            }
        }

        /// <summary>
        /// Esta Propiedad indica si el usuario digito un valor correcto en el buscador.
        /// </summary>
        public bool AWIL_ValorCorrecto
        {
            get
            {
                if (this.textBoxFiltro.ForeColor == Color.Red)
                {
                    return false;
                }
                if (this.textBox2.Text.Trim().Equals(string.Empty))
                {
                    return false;
                }
                return true;
            }
        }
        
        public bool ReadOnly
        {
            get { return this.textBoxFiltro.ReadOnly; }
            set { this.textBoxFiltro.ReadOnly = value; }
        }

        
        private void pictureBoxIcono_Click(object sender, EventArgs e)
        {
            //((DataTable)this.bindingSource.DataSource).Rows
            if (!this.textBoxFiltro.Focused)
                this.textBoxFiltro.Focus();
            this.MostrarVentana();
        }

        private void textBoxFiltro_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyData == (Keys.Control | Keys.B) || e.KeyData == (Keys.F3))
            {
                this.MostrarVentana();
            }
        }

        private void MostrarVentana()
        {
            string filtroAnterior = string.Empty;
            //string filtroActual = string.Empty;

            if (this.textBoxFiltro.ReadOnly)
            {
                return;
            }
            
            if (!this.ventanaBuscador.inicializarVentana(this.bindingSource, this.ocultarColumnas, this.columnaRetorno, this.columnaDescripcion))
            {
                this.Enabled = false;
            }

            if (this.bindingSource == null)
            {
                return;
            }

            //--- Guardo el filtro anterior
            filtroAnterior = (this.bindingSource.Filter != null && this.bindingSource.Filter != string.Empty ? this.bindingSource.Filter.Trim() : string.Empty);
            //--- Muestro la ventana
            this.ventanaBuscador.ShowDialog();
            Thread.Sleep(50);
            //-- Reestablezco el filtro del BindingSource
            this.bindingSource.Filter = filtroAnterior;

            if (this.ventanaBuscador.ok)
            {
                this.AWIL_Texto = this.ventanaBuscador.textoRetorno;
                this.textBox2.Text = this.ventanaBuscador.textoDescripcion;
            }
            this.BringToFront();
            this.pictureBoxIcono.BackgroundImage = (this.textBoxFiltro.ReadOnly?null:global::ControlesAWIL.Properties.Resources.magnifier);
            this.ParentForm.Activate();
        }

        public bool validar()
        {
            if (bindingSource.DataSource==null)
            {
                MessageBox.Show(" el bindingSource.DataSource asociado al buscador '"+this.Name+"' es NULL, Verifique");
                this.Enabled = false;
                return false;
            }

            //--- Verifico que las columnas de retorno y Descripcion existan en el DataMenber indicado
            if (0 > ((DataSet)bindingSource.DataSource).Tables[bindingSource.DataMember].Columns.IndexOf(this.AWIL_ColumnaRetorno))
            {
                MessageBox.Show("La columna de retorno '"+this.columnaRetorno+"' del Buscador '" + this.Name + "' No esta definida en la tabla '" + this.bindingSource.DataMember + "', Verifique");
                this.Enabled = false;
                return false;
            }
            if (0 > ((DataSet)bindingSource.DataSource).Tables[bindingSource.DataMember].Columns.IndexOf(this.AWIL_ColumnaDescripcion))
            {
                MessageBox.Show("La columna de Descripcion '" + this.columnaDescripcion + "' del Buscador '" + this.Name + "' No esta definida en la tabla '" + this.bindingSource.DataMember + "', Verifique");
                this.Enabled = false;
                return false;
            }

            if (!this.AWIL_ValidarCampo)
            {
                this.textBoxFiltro.ForeColor = Color.Black;
                this.dataRowCurrent = null;
                return true;
            }

            
            string filtroAnterior=string.Empty;
            string filtroActual=string.Empty;

            if (this.textBoxFiltro.Text.Trim().Equals(string.Empty))
            {
                this.dataRowCurrent = null;
                return true;
            }

            if (this.bindingSource == null)
            {                
                //this.textBoxFiltro.ForeColor = Color.Red;
                this.dataRowCurrent = null;
                return true;
            }

            if (this.bindingSource.DataSource == null)
            {
                this.textBoxFiltro.ForeColor = Color.Red;
                this.dataRowCurrent = null;
                return true;
            }

            
            Cursor.Current = Cursors.WaitCursor;
            try
            {                
                if (this.bindingSource.Filter!=null)
                {
                    if (!this.bindingSource.Filter.Trim().Equals(string.Empty))
                    {
                        filtroAnterior = this.bindingSource.Filter.Trim();
                        filtroActual = filtroAnterior + " AND ";
                    }                    
                }
                
                //this.bindingSource.RemoveFilter();
                filtroActual += "" + ((DataSet)bindingSource.DataSource).Tables[bindingSource.DataMember].Columns[this.columnaRetorno].ColumnName.ToString() + "";
                filtroActual += " = '" + this.AWIL_Texto.Trim() + "'";
                this.bindingSource.Filter = filtroActual;
                if (this.bindingSource.Count == 0)
                {
                    this.dataRowCurrent = null;
                    this.bindingSource.Filter = filtroAnterior;
                    //this.bindingSource.RemoveFilter();
                    Cursor.Current = Cursors.Default;
                    this.textBox2.Text = string.Empty;
                    
                    //---  si el formulario que tiene el buscador no es el activo del MDI, entonces no muestro el mensaje de error
                    if(this.ParentForm.IsMdiChild)
                    {
                        if (this.ParentForm.MdiParent.ActiveControl == null)
                        {
                            this.textBoxFiltro.ForeColor = Color.Red;
                            return true;
                        }
                        if (!this.ParentForm.MdiParent.ActiveControl.Name.Equals(this.ParentForm.Name))
                        {
                            this.textBoxFiltro.ForeColor = Color.Red;
                            return true;
                        }
                    }

                    if (!this.validarCampo)
                    {
                        this.textBoxFiltro.ForeColor = Color.Black;
                        return true;
                    }
                    this.textBoxFiltro.ForeColor = Color.Red;
                    return false;                                        
                }
                else
                {
                    this.dataRowCurrent = (DataRowView)this.bindingSource.Current;
                    this.AWIL_Texto = ((DataRowView)this.bindingSource.Current)[this.AWIL_ColumnaRetorno].ToString().Trim();
                    this.textBox2.Text = ((DataRowView)this.bindingSource.Current)[this.AWIL_ColumnaDescripcion].ToString().Trim();
                    this.textBoxFiltro.ForeColor = Color.Black;
                    this.bindingSource.Filter = filtroAnterior;
                    Cursor.Current = Cursors.Default;
                    return true;
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
            this.BringToFront();
            this.ParentForm.Activate();
            this.textBoxFiltro.ForeColor = Color.Red;
            this.bindingSource.Filter = filtroAnterior;
            Cursor.Current = Cursors.Default;
            this.dataRowCurrent = null;
            return false;
        }

        private void pictureBoxIcono_MouseMove(object sender, MouseEventArgs e)
        {
            this.pictureBoxIcono.BackgroundImage = (this.textBoxFiltro.ReadOnly ? null : global::ControlesAWIL.Properties.Resources.magnifier);
        }

        private void textBoxFiltro_MouseMove(object sender, MouseEventArgs e)
        {
            this.pictureBoxIcono.BackgroundImage = (this.textBoxFiltro.ReadOnly ? null : global::ControlesAWIL.Properties.Resources.magnifier);
        }

        private void textBoxFiltro_Enter(object sender, EventArgs e)
        {
            valorActual = this.textBoxFiltro.Text.Trim();
            this.pictureBoxIcono.BackgroundImage = (this.textBoxFiltro.ReadOnly ? null : global::ControlesAWIL.Properties.Resources.magnifier);
        }

        private void pictureBoxIcono_MouseLeave(object sender, EventArgs e)
        {
            if (!this.textBoxFiltro.Focused && !this.textBox2.Focused)
                this.pictureBoxIcono.BackgroundImage = null;
        }

        private void textBoxFiltro_MouseLeave(object sender, EventArgs e)
        {
            if (!this.textBoxFiltro.Focused && !this.textBox2.Focused)
                this.pictureBoxIcono.BackgroundImage = null;
        }

        private void textBoxFiltro_Leave(object sender, EventArgs e)
        {
            if(this.valorActual.Trim().Equals(this.textBoxFiltro.Text.Trim()))
            {
                return;
            }

            if (!this.textBox2.Focused && !this.textBoxFiltro.Focused)
            {
                this.pictureBoxIcono.BackgroundImage = null;
            }
            //this.textBoxFiltro.ForeColor = Color.Black;

            if (this.AWIL_FormatoTexto == ControlesAWIL.FormatoTexto.Numero)
            {
                decimal temp = 0;
                if (!this.textBoxFiltro.Text.Trim().Equals(string.Empty) && !decimal.TryParse(this.textBoxFiltro.Text, out temp))
                {
                    MessageBox.Show("Por Favor Digite Un Numero Valido.");
                    this.textBoxFiltro.ForeColor = Color.Red;
                    this.Focus();
                }
                else if (!this.textBoxFiltro.Text.Trim().Equals(string.Empty))
                {
                    this.textBoxFiltro.Text = Math.Round(temp, this.AWIL_NumeroDecimales).ToString();
                }
            }

            //-- Si no se cambio el valor del campo no relaizo la validacion
            if (!valorActual.Equals(this.textBoxFiltro.Text.Trim()))
            {
                //--- Si se digito un valor en el campo, verifico si existe en el BindingSourse Asociado al control
                if (!this.validar())
                {
                    MessageBox.Show("Valor Invalido");
                    if (!this.textBoxFiltro.Text.Trim().Equals(string.Empty))
                    {
                        this.textBoxFiltro.Focus();
                    }
                }
            }
        }

        private void textBox2_Leave(object sender, EventArgs e)
        {
            if (!this.textBox2.Focused && !this.textBoxFiltro.Focused)
            {
                this.pictureBoxIcono.BackgroundImage = null;
            }            
        }

        private void textBoxFiltro_TextChanged(object sender, EventArgs e)
        {
            if (textBoxFiltro.Text.Trim().Equals(string.Empty))
            {
                this.textBox2.Text = string.Empty;
            }
            else 
            {
                this.validar();
            }
        }

    }
}
